/* Pattern.java
 * Author: liuex
 * 2007-12-16 ����12:48:39
 *
 * Note: 
 */
package org.lex.utils.logging.pattern;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.logging.LogRecord;
import java.util.regex.PatternSyntaxException;

public abstract class Pattern {
	private static final String[] EMPTY_STYLES = new String[0];
	private String patternImage = "";
	private int minimalLength = 0;
	private int maximalLength = Integer.MAX_VALUE;
	private boolean leftToRight = true;
	private String[] styles = EMPTY_STYLES;

	public Pattern(String pattern) {
		this(pattern, true);
	}

	/**
	 * <code>pattern</code> like "%-10.25c{style1, style2}"
	 * 
	 * @param pattern
	 * @param parsePattern
	 */
	public Pattern(String pattern, boolean parsePattern) {
		this.patternImage = pattern;
		if (true == parsePattern)
			this.parsePattern(pattern);
	}

	public abstract String format(LogRecord record);

	public String getPatternImage() {
		return patternImage;
	}

	public int getMinimalLength() {
		return minimalLength;
	}

	public int getMaximalLength() {
		return maximalLength;
	}

	public boolean isLeftToRight() {
		return leftToRight;
	}

	public String[] getStyles() {
		return styles;
	}

	public String toString() {
		StringBuilder buf = new StringBuilder();
		buf.append("Original Pattern: ").append(this.patternImage);
		buf.append("\nClass Name: ").append(this.getClass().getName());
		buf.append("\nLeft to Right: ").append(this.leftToRight);
		buf.append("\nMinimal Length: ").append(this.minimalLength);
		buf.append("\nMaximal Length: ").append(this.maximalLength);
		buf.append("\nStyles : ").append(Arrays.toString(this.styles));
		return buf.toString();
	}

	private void parsePattern(String pattern) {
		int start = 1;
		if (pattern.length() > 2 && '-' == pattern.charAt(1)) {
			this.leftToRight = false;
			start = 2;
		}
		int ctrlCharIndex = PatternLexer.findNextControlChar(pattern, start);
		int dotIndex = pattern.indexOf('.');
		if (-1 != dotIndex) {
			// minimal length
			String min = pattern.substring(start, dotIndex);
			if (0 != min.length())
				this.minimalLength = Integer.parseInt(min);
			// maximal length
			String max = pattern.substring(dotIndex + 1, ctrlCharIndex);
			if (0 != max.length())
				this.maximalLength = Integer.parseInt(max);
		}
		if ('}' == pattern.charAt(pattern.length() - 1)) {
			int bracketIndex = pattern.indexOf('{', start);
			if (-1 == bracketIndex)
				throw new PatternSyntaxException("missing '{'", pattern, ctrlCharIndex);
			String style = pattern.substring(bracketIndex + 1, pattern.length() - 1);
			this.styles = this.parseStyles(style);
		}
	}

	private String[] parseStyles(String style) {
		int index = 0;
		ArrayList<String> list = new ArrayList<String>();
		while (index < style.length()) {
			int comma = style.indexOf(',', index);
			if (-1 == comma) {
				String str = style.substring(index, style.length());
				list.add(str.trim());
				break;
			} else {
				String str = style.substring(index, comma);
				list.add(str.trim());
				index = comma + 1;
			}
		}
		return list.toArray(new String[0]);
	}
}
